# -*- coding:utf-8 -*-
import io
import json
import os
import random
import re, uuid
import allure
import traceback
from jsonpath import jsonpath
import base64
import time
from loguru import logger
from PIL.Image import Image


class BaseHelper:

    def extractor(self, obj, expr='.'):
        """根据jsonpath表达式取出value值"""
        try:
            result = jsonpath(obj, expr)[0]
            if result == '{}':
                return
        except Exception as e:  # 不存在该数据，出现异常：'bool' object is not subscriptable  出现该错误的原因是，提取数据时，没有找到该字段
            logger.error(f'关联的接口返回错误，请检查依赖接口是否正常')
            result = {}
        return result

    def rep_expr(self, content, data, expr='&(.+?)&'):
        """从请求参数的字符串中，使用正则的方法找出合适的字符串内容并进行替换

        """
        for ctt in re.findall(expr, content):  # 通过正则取出$.data字符串列表
            content = content.replace(f'&{ctt}&', str(self.extractor(json.loads(data), ctt)))
        return content

    def convert_json(self, dict_str):
        """
            :param dict_str: 长得像字典的字符串
            return json格式的内容
        """
        try:
            if 'null' in dict_str:
                dict_str = dict_str.replace('null', 'None')
            if 'true' in dict_str:
                dict_str = dict_str.replace('true', 'True')
            if 'false' in dict_str:
                dict_str = dict_str.replace('false', 'False')
            dict_str = eval(dict_str)
        except Exception as e:
            if 'None' in dict_str:
                dict_str = dict_str.replace('None', 'null')
            if 'True' in dict_str:
                dict_str = dict_str.replace('True', 'true')
            if 'False' in dict_str:
                dict_str = dict_str.replace('False', 'false')
            dict_str = json.loads(dict_str)
            logger.error(f'{traceback.format_exc()}')
        return dict_str

    def allure_title(self, title):
        """allure中显示的用例标题"""
        allure.dynamic.title(title)

    def allure_description(self, description):
        """allure中显示的用例描述"""
        allure.dynamic.description(description)

    def allure_mode(self, mode):
        """allure中显示的模块"""
        allure.dynamic.story(mode)

    def allure_step(self, step, var):
        """
         :param step: 步骤及附件名称
         :param var: 附件内容
         """
        # with allure.step(step):
        allure.attach(json.dumps(var, ensure_ascii=False, indent=4), step, allure.attachment_type.TEXT)

    def get_uuid(self):
        firList = ["130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "147", "150", "151", "152",
                   "153",
                   "155", "156", "157", "158", "159", "186", "187", "188"]
        return random.choice(firList) + "".join(random.choice("0123456789") for i in range(8))

    def get_last_five_time(self):
        # 当前时间
        # print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        t = time.localtime(time.time() - 300)
        return time.strftime("%Y-%m-%d %H:%M:%S", t)

    def convert_base(self, url):
        # base = open(url, encoding='utf-8')
        with open(url, "r", encoding="utf-8") as f:
            base_str = base64.b64encode(f.read().encode(encoding='utf-8')).decode('ascii')
        return base_str

    def convert_pic(self, content):
        byte_stream = io.BytesIO(content)  # 请求数据转化字节流
        roiImg = Image.open(byte_stream)  # Image打开二进制流Byte字节流数据
        imgByteArr = io.BytesIO()  # 创建一个空的Bytes对象
        roiImg.save(imgByteArr, format='PNG')  # PNG就是图片格式
        imgByteArr = imgByteArr.getvalue()  # 保存的二进制流
        path = '.'
        name = 'test.png'
        # 生成文件目录
        if not os.path.exists(path):
            os.makedirs(path)
        # 创建图片
        with open(path + name, "wb+") as f:
            f.write(imgByteArr)

    def parse_json(self, data_struct_list, json_data, data_struct_link):
        if type(json_data) == type({}):  # 字典类型
            keys_list = json_data.keys()
            for key in keys_list:
                temp_data_struct_link = data_struct_link + '["%s"]' % key
                if type(json_data[key]) not in [type({}), type([])]:  # key对应的value值既不是数组，也不是字典
                    data_struct_list[f'{temp_data_struct_link}'] = json_data[key]
                else:
                    self.parse_json(data_struct_list, json_data[key], temp_data_struct_link)
        elif type(json_data) == type([]):  # 数组类型
            array_length = len(json_data)
            not_key_list = []
            for index in range(0, array_length):
                temp_json_data = json_data[index]
                try:
                    keys_list = temp_json_data.keys()
                except Exception as e:
                    keys_list = []
                    not_key_list.append(temp_json_data)
                    for i in range(len(not_key_list)):
                        temp_not_key_link = data_struct_link + '[%s]' % (str(i))
                        data_struct_list[f'{temp_not_key_link}'] = not_key_list[i]
                for key in keys_list:
                    temp_data_struct_link = data_struct_link + '[%s]["%s"]' % (str(index), key)
                    if type(temp_json_data[key]) not in [type({}), type([])]:  # key对应的value值既不是数组，也不是字典
                        data_struct_list[f'{temp_data_struct_link}'] = temp_json_data[key]
                    else:
                        self.parse_json(data_struct_list, temp_json_data[key], temp_data_struct_link)
        return data_struct_list
